part of 'page.dart';

class _SingleCustomCollectionFolderPageWloc extends StatefulWloc<
    _SingleCustomCollectionFolderPageWlocState,
    SingleCustomCollectionFolderPage> with SingleTickerProviderStateMixin {
  late final bloc.SingleCustomCollectionFolderPageBloc _bloc;

  late Map<Type, NavigationBarTextButtonAutoSizeGroup> navigationButtonAutoSizeGroups;
  late final TextEditingController textEditingController;
  late FocusNode textFieldFocusNode;
  late AnimationController shakeAnimationController;
  late final ScrollController listViewScrollController;

  @override
  _SingleCustomCollectionFolderPageWlocState get initialState {
    return _SingleCustomCollectionFolderPageWlocStateFactory().create(
      blocState: _bloc.state,
    );
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_DefaultState]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionReorderingTilePressed() {
    _bloc.requestCollectionReorderingStart();
  }

  void onCollectionCreationTilePressed() {
    _bloc.requestCollectionCreationStart();
  }

  void onCollectionDeletionTilePressed() {
    _bloc.requestCollectionDeletionStart();
  }

  void onCollectionFolderRenamingTilePressed() {
    _bloc.requestCollectionFolderRenamingStart();
  }

  void onCollectionFolderDeletionTilePressed() {
    _bloc.requestCollectionFolderDeletionStart();
  }

  void _showCollectionFolderDeletionDialog({
    required BuiltList<CollectionFolderDeletionMode> deletionModes,
  }) async {
    final deletionMode = await showAppActionDialog<CollectionFolderDeletionMode?>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          message: SingleCustomCollectionFolderPageTranslation.of(context)
              .collectionFolderDeletionDialogTitle,
          actions: [
            AppActionDialogAction(
              title: SingleCustomCollectionFolderPageTranslation.of(context)
                  .collectionFolderDeletionDialogCollectionFolderAnswer,
              onPressed: () {
                Navigator.of(context).pop(CollectionFolderDeletionMode.collectionFolder);
              },
              isDestructiveAction: true,
            ),
            if (deletionModes
                .contains(CollectionFolderDeletionMode.collectionFolderAndLexicalItems))
              AppActionDialogAction(
                title: SingleCustomCollectionFolderPageTranslation.of(context)
                    .collectionFolderDeletionDialogCollectionFolderAndLexicalItemAnswer,
                onPressed: () {
                  Navigator.of(context)
                      .pop(CollectionFolderDeletionMode.collectionFolderAndLexicalItems);
                },
                isDestructiveAction: true,
              ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (deletionMode != null) {
      _bloc.requestCollectionFolderDeletionCompletion(
        deletionMode: deletionMode,
      );
    }
  }

  void _showDefaultStateCustomLexicalItemDeletionDialog() async {
    final deletionMode = await showAppActionDialog<CollectionFolderDeletionMode?>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          message: SingleCustomCollectionFolderPageTranslation.of(context)
              .lexicalItemDeletionDialogTitle,
          actions: [
            AppActionDialogAction(
              title: SingleCustomCollectionFolderPageTranslation.of(context)
                  .lexicalItemDeletionDialogUniqueLexicalItemAnswer,
              onPressed: () {
                Navigator.of(context)
                    .pop(CollectionFolderDeletionMode.collectionFolderAndExclusiveLexicalItems);
              },
              isDestructiveAction: true,
            ),
            AppActionDialogAction(
              title: SingleCustomCollectionFolderPageTranslation.of(context)
                  .lexicalItemDeletionDialogAllLexicalItemAnswer,
              onPressed: () {
                Navigator.of(context)
                    .pop(CollectionFolderDeletionMode.collectionFolderAndAllLexicalItems);
              },
              isDestructiveAction: true,
            ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (deletionMode != null) {
      _bloc.requestCollectionFolderDeletionCompletion(
        deletionMode: deletionMode,
      );
    }
  }

  void onCollectionTilePressed({
    required String collectionId,
  }) {
    _bloc.requestSingleCollectionPageOpening(
      collectionId: collectionId,
    );
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionReordering]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionReorderingCancellationButtonPressed() {
    _bloc.requestCollectionReorderingCancellation();
  }

  void onCollectionReorderingCompletionButtonPressed() {
    _bloc.requestCollectionReorderingCompletion();
  }

  bool onReorderCollections(Key draggedItemKey, Key newPositionKey) {
    final _state = state;

    if (_state is! _CollectionReordering) {
      return false;
    }

    final draggingIndex = _getReorderableCollectionModelIndexByKey(
      state: _state,
      key: draggedItemKey,
    );

    final newPositionIndex = _getReorderableCollectionModelIndexByKey(
      state: _state,
      key: newPositionKey,
    );

    _bloc.requestReorderableCollectionSwap(
      firstIndex: draggingIndex,
      secondIndex: newPositionIndex,
    );

    return true;
  }

  Key getReorderableCollectionModelKey(_CollectionReorderingCollectionModel collectionModel) {
    return Key(collectionModel.hashCode.toString());
  }

  int _getReorderableCollectionModelIndexByKey({
    required Key key,
    required _CollectionReordering state,
  }) {
    return state.reorderedCollectionModels.indexWhere((collectionModel) {
      final collectionListItemKey = getReorderableCollectionModelKey(collectionModel);
      return collectionListItemKey == key;
    });
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionCreation]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionCreationCancellationButtonPressed() {
    textEditingController.clear();
    _bloc.requestCollectionCreationCancellation();
  }

  void onCollectionCreationCompletionButtonPressed() {
    final collectionTitle = textEditingController.text.trim();
    textEditingController.text = collectionTitle;
    textFieldFocusNode.requestFocus();

    _bloc.requestCollectionCreationCompletion(
      collectionTitleInput: collectionTitle,
    );
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionDeletion]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionDeletionCancellationButtonPressed() {
    _bloc.requestCollectionDeletionCancellation();
  }

  void onCollectionDeletionCompletionButtonPressed() {
    _bloc.requestSelectedCollectionDeletionStart();
  }

  void onCollectionDeletionCollectionTilePressed({
    required String collectionId,
  }) {
    _bloc.requestCollectionDeletionSelectionToggling(
      collectionId: collectionId,
    );
  }

  void onAllCollectionSelectionTilePressed() {
    final _state = state as _CollectionDeletion;

    if (_state.allCollectionSelected) {
      _bloc.requestCollectionDeletionAllCollectionDeselection();
    } else {
      _bloc.requestCollectionDeletionAllCollectionSelection();
    }
  }

  void _showCollectionDeletionDialog({
    required BuiltList<CollectionDeletionMode> deletionModes,
  }) async {
    final deletionMode = await showAppActionDialog<CollectionDeletionMode?>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          message:
              SingleCustomCollectionFolderPageTranslation.of(context).collectionDeletionDialogTitle,
          actions: [
            AppActionDialogAction(
              title: SingleCustomCollectionFolderPageTranslation.of(context)
                  .collectionDeletionDialogCollectionAnswer,
              onPressed: () {
                Navigator.of(context).pop(CollectionDeletionMode.collections);
              },
              isDestructiveAction: true,
            ),
            if (deletionModes.contains(CollectionDeletionMode.collectionsAndLexicalItems))
              AppActionDialogAction(
                title: SingleCustomCollectionFolderPageTranslation.of(context)
                    .collectionDeletionDialogCollectionAndLexicalItemAnswer,
                onPressed: () {
                  Navigator.of(context).pop(CollectionDeletionMode.collectionsAndLexicalItems);
                },
                isDestructiveAction: true,
              ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (deletionMode != null) {
      _bloc.requestSelectedCollectionDeletionCompletion(
        deletionMode: deletionMode,
      );
    }
  }

  void _showCollectionDeletionCustomLexicalItemDeletionDialog() async {
    final deletionMode = await showAppActionDialog<CollectionDeletionMode?>(
      context: context,
      builder: (context) {
        return AppActionDialog(
          message: SingleCustomCollectionFolderPageTranslation.of(context)
              .lexicalItemDeletionDialogTitle,
          actions: [
            AppActionDialogAction(
              title: SingleCustomCollectionFolderPageTranslation.of(context)
                  .lexicalItemDeletionDialogUniqueLexicalItemAnswer,
              onPressed: () {
                Navigator.of(context)
                    .pop(CollectionDeletionMode.collectionsAndExclusiveLexicalItems);
              },
              isDestructiveAction: true,
            ),
            AppActionDialogAction(
              title: SingleCustomCollectionFolderPageTranslation.of(context)
                  .lexicalItemDeletionDialogAllLexicalItemAnswer,
              onPressed: () {
                Navigator.of(context).pop(CollectionDeletionMode.collectionsAndAllLexicalItems);
              },
              isDestructiveAction: true,
            ),
          ],
          onCancelButtonPressed: Navigator.of(context).pop,
        );
      },
    );

    if (deletionMode != null) {
      _bloc.requestSelectedCollectionDeletionCompletion(
        deletionMode: deletionMode,
      );
    }
  }

  // </editor-fold>

  /////////////////////////////////////////////////////////////////////////////////////////////////
  /// [_CollectionFolderRenaming]
  /////////////////////////////////////////////////////////////////////////////////////////////////
  // <editor-fold defaultstate="collapsed">

  void onCollectionFolderRenamingCancellationButtonPressed() {
    _bloc.requestCollectionFolderRenamingCancellation();
  }

  void onCollectionFolderRenamingCompletionButtonPressed() {
    final collectionFolderTitle = textEditingController.text.trim();
    textEditingController.text = collectionFolderTitle;
    textFieldFocusNode.requestFocus();

    _bloc.requestCollectionFolderRenamingCompletion(
      collectionFolderTitleInput: collectionFolderTitle,
    );
  }

  // </editor-fold>

  void _setScrollPositionToTop() {
    if (listViewScrollController.hasClients) {
      listViewScrollController.jumpTo(0);
    }
  }

  void _onBlocStateChanged(
      (
        bloc.SingleCustomCollectionFolderPageBlocState,
        bloc.SingleCustomCollectionFolderPageBlocState
      ) valueWithPrevious) {
    final (blocState, blocPreviousState) = valueWithPrevious;

    final updatedState = _SingleCustomCollectionFolderPageWlocStateFactory().create(
      blocState: _bloc.state,
    );

    emit(updatedState);

    if (blocPreviousState.runtimeType != blocState.runtimeType) {
      _setScrollPositionToTop();
    }

    if (blocState is bloc.DefaultState) {
      if (blocState.collectionFolderDeletionDialogStatusInfo.shown) {
        _showCollectionFolderDeletionDialog(
          deletionModes: blocState.collectionFolderDeletionDialogStatusInfo.deletionModes,
        );
      }
      if (blocState.customLexicalItemDeletionDialogShown) {
        _showDefaultStateCustomLexicalItemDeletionDialog();
      }
    } else if (blocState is bloc.CollectionDeletion) {
      if (blocState.collectionDeletionDialogStatusInfo.shown) {
        _showCollectionDeletionDialog(
          deletionModes: blocState.collectionDeletionDialogStatusInfo.deletionModes,
        );
      }
      if (blocState.customLexicalItemDeletionDialogShown) {
        _showCollectionDeletionCustomLexicalItemDeletionDialog();
      }
    } else if (blocState is bloc.CollectionCreation) {
      if (blocState.validationError != null) {
        shakeAnimationController.forward(from: 0.0);
      }
    } else if (blocState is bloc.CollectionFolderRenaming) {
      if (blocState.validationError != null) {
        shakeAnimationController.forward(from: 0.0);
      }
    }

    if (blocPreviousState is bloc.CollectionCreation && blocState is! bloc.CollectionCreation) {
      textEditingController.clear();
    }

    if (blocPreviousState is bloc.CollectionFolderRenaming &&
        blocState is! bloc.CollectionFolderRenaming) {
      textEditingController.clear();
    }

    if (blocPreviousState is! bloc.CollectionFolderRenaming &&
        blocState is bloc.CollectionFolderRenaming) {
      textEditingController.text = blocState.collectionFolder.title;
      textFieldFocusNode.requestFocus();
    }

    if (blocPreviousState is! bloc.CollectionCreation && blocState is bloc.CollectionCreation) {
      textFieldFocusNode.requestFocus();
    }
  }

  @override
  void initState() {
    super.initState();

    _bloc = bloc.SingleCustomCollectionFolderPageBloc(
      pageModel: widget.pageModel,
      learningContentBloc: core_di.sl(),
      userInfoBloc: core_di.sl(),
      overlayBloc: core_di.sl(),
      collectionNavigatorBloc: core_di.sl(),
      purchaseFlowDisplayBloc: core_di.sl(),
      getInitialData: single_custom_collection_folder_page_di.sl(),
      cancelCollectionDeletion: single_custom_collection_folder_page_di.sl(),
      cancelCollectionReordering: single_custom_collection_folder_page_di.sl(),
      completeCollectionCreation: single_custom_collection_folder_page_di.sl(),
      completeSelectedCollectionDeletion: single_custom_collection_folder_page_di.sl(),
      completeCollectionFolderDeletion: single_custom_collection_folder_page_di.sl(),
      completeCollectionFolderRenaming: single_custom_collection_folder_page_di.sl(),
      completeCollectionReordering: single_custom_collection_folder_page_di.sl(),
      deselectAllCollectionsDuringCollectionDeletion: single_custom_collection_folder_page_di.sl(),
      handleCollectionCreationLearningContentOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionCreationPremiumAccessStatusOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionDeletionLearningContentOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionDeletionPremiumAccessStatusOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionFolderRenamingLearningContentOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionFolderRenamingPremiumAccessStatusOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionReorderingLearningContentOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleCollectionReorderingPremiumAccessStatusOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      handleDefaultStateLearningContentOuterUpdate: single_custom_collection_folder_page_di.sl(),
      handleDefaultStatePremiumAccessStatusOuterUpdate:
          single_custom_collection_folder_page_di.sl(),
      selectAllCollectionsDuringCollectionDeletion: single_custom_collection_folder_page_di.sl(),
      startCollectionDeletion: single_custom_collection_folder_page_di.sl(),
      startCollectionFolderDeletion: single_custom_collection_folder_page_di.sl(),
      startSelectedCollectionDeletion: single_custom_collection_folder_page_di.sl(),
      swapCollections: single_custom_collection_folder_page_di.sl(),
      toggleCollectionDeletionSelection: single_custom_collection_folder_page_di.sl(),
    );

    _bloc.streamWithPrevious.listen(_onBlocStateChanged);

    navigationButtonAutoSizeGroups = {
      _CollectionReordering: NavigationBarTextButtonAutoSizeGroup(),
      _CollectionCreation: NavigationBarTextButtonAutoSizeGroup(),
      _CollectionDeletion: NavigationBarTextButtonAutoSizeGroup(),
      _CollectionFolderRenaming: NavigationBarTextButtonAutoSizeGroup(),
    };

    textEditingController = TextEditingController();
    textFieldFocusNode = FocusNode();

    shakeAnimationController = AnimationController(
      duration: const Duration(milliseconds: 200),
      vsync: this,
    );

    listViewScrollController = ScrollController();
  }

  @override
  void dispose() {
    _bloc.close();
    textEditingController.dispose();
    textFieldFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _SingleCustomCollectionFolderPageView(
      wloc: this,
    );
  }
}
